<template>
  <div class="camera-container">
    <!-- 相机预览区域 -->
    <div class="camera-preview" v-if="!imageUrl">
      <video 
        ref="video" 
        class="video-preview" 
        autoplay 
        playsinline
        :width="videoWidth"
        :height="videoHeight"
      ></video>
      
      <!-- 拍照按钮 -->
      <button 
        class="capture-btn" 
        @click="takePhoto"
        :disabled="isProcessing"
      >
        <i class="icon-camera"></i>
      </button>
      
      <!-- 错误信息 -->
      <div class="error-message" v-if="errorMessage">{{ errorMessage }}</div>
    </div>
    
    <!-- 图片预览区域 -->
    <div class="image-preview" v-if="imageUrl">
      <img :src="imageUrl" alt="拍摄的照片" class="captured-image">
      <div class="image-actions">
        <button class="action-btn re-take" @click="reTakePhoto">重拍</button>
        <button class="action-btn confirm" @click="confirmPhoto">确认使用</button>
      </div>
      <div class="base64-info">
        <p>Base64 图片已生成</p>
        <button class="copy-btn" @click="copyBase64">复制Base64</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CameraCapture',
  data() {
    return {
      // 视频相关配置
      videoWidth: 320,
      videoHeight: 480,
      stream: null,
      
      // 图片相关
      imageUrl: '',  // 存储base64格式图片
      isProcessing: false,
      
      // 错误信息
      errorMessage: ''
    }
  },
  
  mounted() {
    // 页面加载完成后初始化相机
    this.initCamera();
  },
  
  beforeDestroy() {
    // 组件销毁前停止相机流，释放资源
    this.stopCamera();
  },
  
  methods: {
    /**
     * 初始化相机
     */
    async initCamera() {
      try {
        // 获取视频元素
        const video = this.$refs.video;
        
        // 请求相机权限并获取媒体流
        this.stream = await navigator.mediaDevices.getUserMedia({
          video: { 
            width: this.videoWidth,
            height: this.videoHeight,
            facingMode: 'environment' // 使用后置摄像头，'user'为前置
          }
        });
        
        // 将媒体流分配给视频元素
        video.srcObject = this.stream;
        
        // 清除错误信息
        this.errorMessage = '';
      } catch (error) {
        console.error('相机初始化失败:', error);
        this.errorMessage = '无法访问相机，请确保已授予相机权限';
      }
    },
    
    /**
     * 停止相机流，释放资源
     */
    stopCamera() {
      if (this.stream) {
        this.stream.getTracks().forEach(track => {
          track.stop();
        });
        this.stream = null;
      }
    },
    
    /**
     * 拍照并转换为base64格式
     */
    takePhoto() {
      if (this.isProcessing) return;
      
      this.isProcessing = true;
      
      try {
        // 创建canvas元素用于捕获视频帧
        const canvas = document.createElement('canvas');
        canvas.width = this.videoWidth;
        canvas.height = this.videoHeight;
        
        // 获取视频元素
        const video = this.$refs.video;
        
        // 在canvas上绘制当前视频帧
        const context = canvas.getContext('2d');
        context.drawImage(video, 0, 0, canvas.width, canvas.height);
        
        // 将canvas内容转换为base64格式的图片
        // 0.9表示图片质量，范围0-1
        this.imageUrl = canvas.toDataURL('image/jpeg', 0.9);
        
        // 停止相机流
        this.stopCamera();
      } catch (error) {
        console.error('拍照失败:', error);
        this.errorMessage = '拍照失败，请重试';
      } finally {
        this.isProcessing = false;
      }
    },
    
    /**
     * 重新拍照
     */
    reTakePhoto() {
      this.imageUrl = '';
      this.initCamera();
    },
    
    /**
     * 确认使用照片
     * 触发事件将base64图片传递给父组件
     */
    confirmPhoto() {
      this.$emit('photo-confirmed', this.imageUrl);
    },
    
    /**
     * 复制base64字符串到剪贴板
     */
    copyBase64() {
      if (!this.imageUrl) return;
      
      navigator.clipboard.writeText(this.imageUrl)
        .then(() => {
          alert('Base64已复制到剪贴板');
        })
        .catch(err => {
          console.error('复制失败:', err);
          alert('复制失败，请手动复制');
        });
    }
  }
}
</script>

<style scoped>
.camera-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background-color: #f5f5f5;
  padding: 20px;
  box-sizing: border-box;
}

.camera-preview {
  position: relative;
  width: 100%;
  max-width: 400px;
}

.video-preview {
  width: 100%;
  height: auto;
  border-radius: 10px;
  background-color: #000;
  object-fit: cover;
}

.capture-btn {
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background-color: #ffffff;
  border: 4px solid #42b983;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  outline: none;
  padding: 0;
}

.capture-btn:disabled {
  background-color: #cccccc;
  border-color: #999999;
}

.icon-camera {
  width: 30px;
  height: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%2342b983' d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
}

.error-message {
  color: #ff4444;
  margin-top: 20px;
  text-align: center;
  font-size: 14px;
}

.image-preview {
  width: 100%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.captured-image {
  width: 100%;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.image-actions {
  display: flex;
  justify-content: space-around;
  width: 100%;
  margin-top: 20px;
  gap: 20px;
}

.action-btn {
  flex: 1;
  padding: 12px 0;
  border: none;
  border-radius: 5px;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  transition: background-color 0.3s;
}

.re-take {
  background-color: #f8f8f8;
  color: #333;
  border: 1px solid #ddd;
}

.re-take:hover {
  background-color: #e0e0e0;
}

.confirm {
  background-color: #42b983;
  color: white;
}

.confirm:hover {
  background-color: #359e6d;
}

.base64-info {
  margin-top: 20px;
  font-size: 14px;
  color: #666;
  text-align: center;
}

.copy-btn {
  margin-top: 10px;
  padding: 8px 16px;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.copy-btn:hover {
  background-color: #0b7dda;
}
</style>
